#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <time.h>
#include <stdlib.h>
#include <syslog.h>
#include "SDL.h"
#include "PDL.h"

#include <pthread.h>

#include <SDL_events.h>

void *start_recording(void *ptr);
void *stop_recording(void *ptr);
void *start_playing(void *ptr);

unsigned int duration = 1;

char CBParam[128] = {0};

PDL_bool DeleteOld(PDL_JSParameters *params)
{
	char reply[64];
	//
	int ret1 = system("rm -f /media/internal/recording.wav"); // delete the previous recorded file
	if (ret1 == -1){
		snprintf(reply, 64, "Audio Record--Delete Old File Fail!!");
		PDL_JSReply(params, reply);
		return PDL_TRUE;	
	}else{
		snprintf(reply, 64, "Audio Record--Delete Old File OK!!");
		PDL_JSReply(params, reply);
		return PDL_TRUE;	
	}
}

PDL_bool Record(PDL_JSParameters *params)
{
	char reply[64];
	
	syslog(LOG_INFO, "SamDebug: %s\n", __func__);
	
	duration = (unsigned int)atoi(PDL_GetJSParamString(params, 0));
	
	pthread_t 	thread_recording;
	int 		thread_recording_id;
	
	thread_recording_id = pthread_create(&thread_recording, NULL, start_recording, NULL);
	syslog(LOG_INFO, "SamDebug: %s, create stop thread, thread_recording_id = %d(%s)\n", __func__, thread_recording_id, strerror(thread_recording_id));
	if (thread_recording_id != 0){
		snprintf(reply, 64, "Audio Record Start Fail");
		PDL_JSReply(params, reply);
		return PDL_TRUE;	
	}	
	
	pthread_t 	thread_touch;
	int 		thread_id;
	thread_id = pthread_create(&thread_touch, NULL, stop_recording, NULL);
	syslog(LOG_INFO, "SamDebug: %s, create stop thread, thread_id = %d(%s)\n", __func__, thread_id, strerror(thread_id));
	if (thread_id != 0){
		/*TODO: Need some code to kill start_recording thread. */
		
		snprintf(reply, 64, "Audio Record Start Fail");
		PDL_JSReply(params, reply);		
		return PDL_TRUE;	
	}
	
	snprintf(reply, 64, "Audio Record Start OK");
	PDL_JSReply(params, reply);
	return PDL_TRUE;
}



PDL_bool Play(PDL_JSParameters *params)
{
	char reply[64];
	
	pthread_t 	thread_playing;
	int 		thread_playing_id;
	
	thread_playing_id = pthread_create(&thread_playing, NULL, start_playing, NULL);
	syslog(LOG_INFO, "SamDebug: %s, create stop thread, thread_playing = %d(%s)\n", __func__, thread_playing_id, strerror(thread_playing_id));
	if (thread_playing_id != 0){
		snprintf(reply, 64, "Audio Play Start Fail");
	} else {
		snprintf(reply, 64, "Audio Play Start OK");
	}

	PDL_JSReply(params, reply);
	return PDL_TRUE;
}

PDL_bool Quit(PDL_JSParameters *params)
{
	SDL_QuitEvent quitEvent;
	quitEvent.type = SDL_QUIT;
	SDL_PushEvent((SDL_Event*)&quitEvent);
	
	return PDL_TRUE;
}

int main(int argc, char** argv)
{
  openlog("com.hp.testvoicerecording", 0, LOG_USER);
  
  syslog(LOG_INFO, "SamDebug: main\n");
  
  system("rootfs_open");
  system("echo pardon > /etc/nojail");
    
  if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
  {
    printf("Could not init SDL: %s\n", SDL_GetError());
    exit(1);
  }
  
  PDL_Init(0);
  
  syslog(LOG_INFO, "SamDebug: before registering js call back\n");
  
  // register the js callback
  PDL_RegisterJSHandler("DeleteOld", DeleteOld);
  PDL_RegisterJSHandler("Record", Record);
  PDL_RegisterJSHandler("Play", Play);
  PDL_RegisterJSHandler("Quit", Quit);
  PDL_JSRegistrationComplete();
  
  syslog(LOG_INFO, "SamDebug: completing registering js call back\n");
  
  // Event descriptor
  SDL_Event event;
  
  //Loop till SDL_QUIT comes
  do
  {
    SDL_PollEvent(&event);    
  } while (event.type != SDL_QUIT);
  
  system("killall -9 parec");
  system("killall -9 aplay");
  
  // Cleanup
  PDL_Quit();
  SDL_Quit();
  closelog();
}

void *start_recording(void *ptr){
	/*TODO: Pease note maybe this thread should be killed as stop_recording thread failure. */
	system("parec -r -v --device=pcm_input --channels=2 --rate=48000 --format=s16le /media/internal/recording.wav");
}


void *stop_recording(void *ptr){
	struct timespec req;
	struct timespec rem;
	req.tv_sec 	= duration;
	req.tv_nsec = 0; // nano-seconds
	syslog(LOG_INFO, "SamDebug: %s, Before sleep, duration = %d\n", __func__, duration);
	nanosleep(&req, &rem);
	syslog(LOG_INFO, "SamDebug: %s, after sleep\n", __func__);
	int ret = system("killall -9 parec");
	syslog(LOG_INFO, "SamDebug: %s, kill parec %d\n", __func__, ret);
	if (ret==-1){
		const char *params[1];
		sprintf(CBParam, "Audio Record Stop Fail--Can Not Stop");
		params[0] = CBParam;
		PDL_Err mjErr = PDL_CallJS("StopFailReport", params, 1);
	} else {
		const char *params[1];
		sprintf(CBParam, "Audio Record Stop OK");
		params[0] = CBParam;
		PDL_Err mjErr = PDL_CallJS("StopFailReport", params, 1);
	}
}

void *start_playing(void *ptr){
	const char *params[1];
	system("aplay -D media /media/internal/recording.wav -f S16_LE -r 44100 -c 2");
	
	sprintf(CBParam, "Audio Play Stop OK");
	params[0] = CBParam;
	PDL_Err mjErr = PDL_CallJS("PlayCompleted", params, 1);
}